# -*- makefile -*-
# vi:se ft=make:

# Include for unit tests, enable by including UTEST in SUBSYSTEMS.
include $(srcdir)/test/utest/Modules.utest
# Include for code rules tests, enable by including CODERULES in SUBSYSTEMS.
include $(srcdir)/test/coderules/Modules.crtest

SUBSYSTEMS += ABI JABI KERNEL DRIVERS CRT0 VERSION TCBOFFSET STDWORKLOAD
SUBSYSTEMS += LIBK CXXLIB LIBC

ifeq ($(CONFIG_UNIT_TEST),y)
  # UTEST depends on KERNEL and CHECKSUM, must be listed after them
  SUBSYSTEMS += UTEST
endif

ifeq ($(CONFIG_CODE_RULES_TEST),y)
  SUBSYSTEMS += CODERULES
endif

#
# ABI Subsystem
#
ABI		:= libabi.a
VPATH 		+= abi/$(CONFIG_XARCH)/$(BITS) abi/$(CONFIG_XARCH) abi
INTERFACES_ABI 	:= kip l4_types l4_fpage l4_msg_item l4_buf_desc l4_error

l4_types_IMPL 	:= l4_types l4_types-debug
kip_IMPL	:= kip kip-debug kip-$(CONFIG_XARCH)



INTERFACES_KERNEL	:= cpu_mask rcupdate kobject_mapdb context_base pm \
			   mem_region per_cpu_data startup                   \
			   queue queue_item l4_buf_iter bitmap               \
			   mapping spin_lock mapping_tree                    \
			   dbg_page_info mapdb pic kobject_dbg koptions      \
			   kobject_iface kobject ready_queue_wfq             \
                           obj_space_types obj_space_phys_util \
			   ready_queue_fp obj_space ptab_base ram_quota      \
			   ref_obj mem_space space \
			   vlog kmem kmem_alloc kmem_mmio slab_cache         \
			   mem_layout kmem_slab switch_lock kip_init         \
			   helping_lock cpu_lock timer timeout   \
			   ipc_timeout timeslice_timeout per_cpu_data_alloc  \
			   vcpu_host_regs                                    \
			   vcpu kobject_helper icu_helper thread_state       \
			   context sender receiver mem_unit factory cpu_call \
			   ipc_sender thread thread_object syscalls          \
			   kernel_thread map_util irq banner warn            \
			   app_cpu_thread globals watchdog kernel_uart       \
			   main config vmem_alloc page paging paging_bits    \
			   fpu fpu_state_ptr fpu_alloc cpu entry_frame       \
			   kernel_console ipc_gate task sigma0_task          \
                           kernel_task platform_control_object          \
			   irq_controller irq_chip irq_mgr terminate         \
			   continuation timer_tick platform_control          \
			   sched_context utcb_init perf_cnt trap_state       \
			   buddy_alloc vkey kdb_ke prio_list ipi scheduler   \
			   clock sys_call_page boot_alloc                    \
			   semaphore jdb_object tlbs amp_node global_data

OBJ_SPACE_TYPE = $(if $(CONFIG_VIRT_OBJ_SPACE),virt,phys)
PREPROCESS_PARTS-y$(CONFIG_VIRT_OBJ_SPACE) += obj_space_phys
PREPROCESS_PARTS += obj_space_$(OBJ_SPACE_TYPE)
INTERFACES_KERNEL-$(CONFIG_VIRT_OBJ_SPACE) += obj_space_virt_util
INTERFACES_KERNEL-y$(CONFIG_NDEBUG) += assertion
obj_space_IMPL = obj_space obj_space-$(OBJ_SPACE_TYPE)
PREPROCESS_PARTS-$(CONFIG_PHYS_OBJ_SPACE_AVL) += obj_space_phys_avl


platform_control_IMPL   := platform_control

syscalls_IMPL		:= syscalls syscalls-log

timer_tick_IMPL         := timer_tick

vcpu_host_regs_IMPL	:= vcpu_host_regs-$(CONFIG_XARCH)

kdb_ke_IMPL             := kdb_ke

INTERFACES_STDWORKLOAD := std_workload

INTERFACES_JDB += \
	jdb_types                                                          \
	jdb jdb_util jdb_core jdb_module jdb_prompt_ext jdb_list           \
	jdb_handler_queue jdb_attach_irq jdb_entry_frame                   \
	jdb_exit_module jdb_bp jdb_factory jdb_input jdb_ipc_gate          \
	jdb_prompt_module                    \
	jdb_obj_space jdb_screen jdb_table jdb_tcb               \
	jdb_thread jdb_thread_list kern_cnt jdb_counters push_console      \
	jdb_regex jdb_disasm jdb_tbuf_output jdb_input_task jdb_tbuf_show  \
	jdb_report jdb_dump jdb_mapdb jdb_timeout jdb_kern_info_kmem_alloc \
	jdb_kern_info_kip jdb_kern_info jdb_kern_info_data jdb_utcb        \
	jdb_trap_state jdb_rcupdate jdb_sender_list jdb_tbuf_fe            \
	jdb_cpu_call jdb_ipi

INTERFACES_JDB-$(CONFIG_TICKLESS_IDLE) += jdb_idle_stats

jdb_IMPL	+= jdb jdb-ansi jdb-thread
jdb_tbuf_IMPL	+= jdb_tbuf jdb_tbuf-$(CONFIG_XARCH)
jdb_tcb_IMPL	+= jdb_tcb

ifeq ($(CONFIG_RT_DBG),y)
INTERFACES_KERNEL += \
	jdb_kobject jdb_kobject_names jdb_space
endif

ifeq ("$(CONFIG_JDB)","y")
INTERFACES_KERNEL += \
	jdb_tbuf jdb_tbuf_init tb_entry jdb_trace string_buffer
endif

# - do not profile all of LIBC, because it is used in the BOOT subsystem
# - save some space for debugger, disassembler, ...
NOOPT			+= $(patsubst %.o, %,\
			   $(OBJ_LIBC) $(OBJ_JDB) $(OBJ_LIBDISASM))

# Helper function to generate CXXFLAGS_uart-libuart
LIBUART_UART = -include uart_$(strip $(1)).h \
	       -DFIASCO_UART_TYPE=L4::Uart_$(strip $(if $(2),$(2),$(1)))

LIBUART_UART2 = -include uart_$(strip $(1)).h \
		-DFIASCO_UART2_TYPE=L4::Uart_$(strip $(if $(2),$(2),$(1)))

#
# COV Subsystem
#
ifneq ($(CONFIG_COV),)

LIBCOV_CONTRIB_SUPPORTED_VERSIONS := 17 18 19 20
LIBCOV_CONTRIB_MIN_VERSION        := $(lastword $(LIBCOV_CONTRIB_SUPPORTED_VERSIONS))
LIBCOV_CONTRIB_VERSION            := $(CCVER_VERSION)

ifeq ($(filter $(LIBCOV_CONTRIB_VERSION),$(LIBCOV_CONTRIB_SUPPORTED_VERSIONS)),)
  $(warning No suitable libcov version found for clang $(LIBCOV_CONTRIB_VERSION).)
  $(warning Falling back to libcov $(LIBCOV_CONTRIB_MAX_VERSION), unexpected errors may occur.)
  $(warning Please update the libcov package.)
  LIBCOV_CONTRIB_VERSION   := $(LIBCOV_CONTRIB_MAX_VERSION)
endif

LIBCOV := libcov.a
VPATH += lib/gcov/src
VPATH += lib/gcov/contrib/llvm_compiler-rt_profile/llvm-$(LIBCOV_CONTRIB_VERSION)/
PRIVATE_INCDIR += lib/gcov/src
PRIVATE_INCDIR += lib/gcov/contrib/llvm_compiler-rt_profile/llvm-$(LIBCOV_CONTRIB_VERSION)/

CSRC_LIBCOV-clang_contrib := \
        InstrProfiling.c InstrProfilingBuffer.c InstrProfilingPlatformLinux.c \
        InstrProfilingVersionVar.c InstrProfilingWriter.c                     \
        InstrProfilingInternal.c

CSRC_LIBCOV-clang := llvmcov.c plain.c llvmcov-plain.c
CSRC_LIBCOV-clang += $(CSRC_LIBCOV-clang_contrib)

CSRC_LIBCOV-gcc   := gcov.c plain.c gcov-plain.c

CSRC_LIBCOV        = output.c base64.c
CSRC_LIBCOV       += $(CSRC_LIBCOV-$(CC_TYPE))

CSRC_LIBCOV       += $(if $(CONFIG_COV_OUTPUT_SERIAL),output-serial.c)
CXXSRC_LIBCOV     += $(if $(CONFIG_COV_OUTPUT_MEMBUF),output-membuf.cc)

# WARNING EXCEPTION: suppress compiler warnings for clang compiler-rt code,
# only coverage tooling
$(foreach f, $(patsubst %.c, %, $(CSRC_LIBCOV-clang_contrib)), \
        $(eval CFLAGS_$(f) += -Wno-strict-prototypes -Wno-unused-parameter \
                              -Wno-missing-prototypes -Wno-undef))

NOOPT += $(patsubst %.o, %, $(OBJ_LIBCOV))

endif

#
# LIBC Subsystem
#
LIBC_ARCH-arm-    := arm
LIBC_ARCH-arm-y   := aarch64
LIBC_ARCH-ia32-   := i386
LIBC_ARCH-amd64-y := x86_64
LIBC_ARCH-mips-   := mips
LIBC_ARCH-mips-y  := mips64
LIBC_ARCH-riscv-  := riscv32
LIBC_ARCH-riscv-y := riscv64
LIBC_ARCH-ppc-    := powerpc
LIBC_ARCH-sparc-  := sparc
LIBC_ARCH         := $(LIBC_ARCH-$(CONFIG_XARCH)-$(CONFIG_BIT64))
LIBC              := libc.a
VPATH             += lib/libc/glue \
                     lib/libc/src/string \
                     lib/libc/src/ctype \
                     lib/libc/src/errno \
                     lib/libc/src/stdio \
                     lib/libc/src/exit \
                     lib/libc/src/stdlib \
                     lib/libc/src/internal \
                     lib/libc/src/setjmp/$(LIBC_ARCH)
PRIVATE_INCDIR    += lib/libc/arch/$(LIBC_ARCH) \
                     lib/libc/src/internal \
                     lib/libc/src/include \
                     lib/libc/include
CPPFLAGS          += -DLIBCL4
CSRC_LIBC         := putchar.c \
                     putstr.c \
                     stdout_write.c \
                     \
                     memchr.c \
                     memmove.c \
                     memset.c \
                     memcmp.c \
                     strlen.c \
                     strnlen.c \
                     strcpy.c \
                     strncpy.c \
                     strcmp.c \
                     stpcpy.c \
                     strchr.c \
                     $(if $(filter ia32,$(CONFIG_XARCH)),,memcpy.c) \
                     strcspn.c \
                     strchrnul.c \
                     stpncpy.c \
                     strrchr.c \
                     memrchr.c \
                     strncmp.c \
                     \
                     strtol.c \
                     \
                     isalnum.c \
                     isalpha.c \
                     isdigit.c \
                     isprint.c \
                     isxdigit.c \
                     isspace.c \
                     tolower.c \
                     \
                     printf.c \
                     snprintf.c \
                     sprintf.c \
                     vfprintf.c \
                     vsnprintf.c \
                     vsprintf.c \
                     vprintf.c \
                     __towrite.c \
                     fputs.c \
                     fwrite.c \
                     puts.c \
                     \
                     atexit.c \
                     \
                     intscan.c

CXXSRC_LIBC += strstr.cc

# riscv32: needed by intscan.c
VPATH             += lib/libk/quad
CSRC_LIBC         += lshrdi3.c
ASSRC_LIBC        := setjmp.S longjmp.S \
                     $(if $(filter ia32,$(CONFIG_XARCH)),memcpy-i386.S)
NOBUILTIN         += $(patsubst %.o, %, $(OBJ_LIBC))
